import java.util.ArrayList;

import javax.media.opengl.GL;

import com.sun.opengl.util.texture.Texture;

//this class is the implementation of level 2 drawing. it define the level's room and light.
public class Level2Builder  extends LevelBuilder{
	

	private int room;
	ArrayList<Point3D[]> roomsWall;
	Point3D[] floorAbyss;
	private int door;
	private int door1Pos;
	private int door2Pos;
	private double doorPosHight;
	private Switcher switcher;
	
	// ctor
	public Level2Builder(Switcher switcher) {
		roomsWall = new ArrayList<Point3D[]>(4) ;
		this.switcher=switcher;
	}

	
	public void buildMap(GL gl){
		leftWall=1800;
		rightWall=0;
		forwardWall=1800;
		backWall=0;
		celling=2000;
		floor=0;
		
		door1Pos=800;
		door2Pos=500;
		
		double doors [] ={0,0,0,0,door1Pos,door2Pos,0,0};
		room=make_room(gl,forwardWall,celling,leftWall,doors,wallTexture,floorTexture,cellingTexture,500,500,0);
		make_door(gl,celling,door1Pos-door2Pos);
		
		

		
	}
	

 private void make_door(GL gl,float hight,float width) {
	 	door = gl.glGenLists(1);
	 	
	 	gl.glNewList(door, GL.GL_COMPILE);
		gl.glEnd();
		gl.glBegin(GL.GL_QUAD_STRIP);
		
		
		gl.glVertex3d(0, 0, 0);
		gl.glVertex3d(0, hight, 0);

		
		gl.glVertex3d(10, 0, 0);
		gl.glVertex3d(10, hight, 0);

		
		gl.glVertex3d(10, 0, width);
		gl.glVertex3d(10, hight, width);

		
		gl.glVertex3d(0, 0, width);
		gl.glVertex3d(0, hight, width);

		
		gl.glVertex3d(0, 0, 0);
		gl.glVertex3d(0, hight, 0);
		gl.glVertex3d(0, hight, 0);
		gl.glVertex3d(0, hight, width);
		gl.glVertex3d(10, hight, 0);
		gl.glVertex3d(10, hight, width);
		
		gl.glEnd();
	    gl.glEndList();
	}


private int make_room(GL gl,double sizeX,double sizeY,double sizeZ,double[] doors,Texture wallTexture,Texture floorTexture,Texture cellingTexture,float startAbyss,float endAbyss,float disp){
	 	Point3D[] roomWall = new Point3D[6];

		int room = gl.glGenLists(1);

		gl.glNewList(room, GL.GL_COMPILE);

        gl.glTexParameteri ( GL.GL_TEXTURE_2D,GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT );
        gl.glTexParameteri( GL.GL_TEXTURE_2D,GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT );
//        gl.glTexParameteri( GL.GL_TEXTURE_2D,GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP );

 		//walls
        wallTexture.bind();
		gl.glBegin(GL.GL_QUAD_STRIP);

		roomWall[0]=(new Point3D(0+disp, 0, 0));
		
		
		gl.glTexCoord2f(0.0f, 0.0f);
		gl.glVertex3d(0, 0, 0);
		gl.glTexCoord2f(0.0f,4.0f);
		gl.glVertex3d(0, sizeY, 0);
		
		
		gl.glTexCoord2f((float)(8/(sizeX/doors[0])), 0.0f);
		gl.glVertex3d(doors[0], 0, 0);
		
		gl.glTexCoord2f((float)(8/(sizeX/doors[0])), 4f);
		gl.glVertex3d(doors[0], sizeY, 0);
		

		
		
		gl.glEnd();
		gl.glBegin(GL.GL_QUAD_STRIP);

		gl.glTexCoord2f(0f, 0.0f);
		gl.glVertex3d(doors[1], 0, 0);
		gl.glTexCoord2f(0f, 4f);
		gl.glVertex3d(doors[1], sizeY, 0);

		roomWall[1]=(new Point3D(sizeX+disp, 0, 0));
		
		gl.glTexCoord2f(8f, 0.0f);
		gl.glVertex3d(sizeX, 0, 0);
		gl.glTexCoord2f(8f, 4f);
		gl.glVertex3d(sizeX, sizeY, 0);

		
		gl.glTexCoord2f(0.0f, 0.0f);
		gl.glVertex3d(sizeX, 0, doors[2]);
		gl.glTexCoord2f(0.0f,4.0f);
		gl.glVertex3d(sizeX, sizeY, doors[2]);
		
		gl.glEnd();
		gl.glBegin(GL.GL_QUAD_STRIP);
		
		gl.glTexCoord2f(0.0f, 0.0f);
		gl.glVertex3d(sizeX, 0, doors[3]);
		gl.glTexCoord2f(0.0f,4.0f);
		gl.glVertex3d(sizeX, sizeY, doors[3]);
		
		roomWall[2]=(new Point3D(sizeX+disp, 0, sizeZ));
		
		gl.glTexCoord2f(8f, 0.0f);
		gl.glVertex3d(sizeX, 0, sizeZ);
		gl.glTexCoord2f(8f,4.0f);
		gl.glVertex3d(sizeX, sizeY, sizeZ);
		
	
		
		gl.glTexCoord2f(4.0f, 0.0f);
		gl.glVertex3d(doors[4], 0, sizeZ);
		gl.glTexCoord2f(4.0f,4.0f);
		gl.glVertex3d(doors[4], sizeY, sizeZ);
		
		gl.glEnd();
		gl.glBegin(GL.GL_QUAD_STRIP);
		
		gl.glTexCoord2f(6.0f, 0.0f);
		gl.glVertex3d(doors[5], 0, sizeZ);
		gl.glTexCoord2f(6.0f,4.0f);
		gl.glVertex3d(doors[5], sizeY, sizeZ);
		
		roomWall[3]=(new Point3D(0+disp, 0, sizeZ));
	
		gl.glTexCoord2f(8f, 0.0f);
		gl.glVertex3d(0, 0, sizeZ);
		gl.glTexCoord2f(8f, 4f);
		gl.glVertex3d(0, sizeY, sizeZ);
///
		gl.glTexCoord2f(0.0f, 0.0f);
		gl.glVertex3d(0, 0, doors[6]);
		gl.glTexCoord2f(0.0f,4.0f);
		gl.glVertex3d(0, sizeY, doors[6]);
		
		gl.glEnd();
		gl.glBegin(GL.GL_QUAD_STRIP);
		
		gl.glTexCoord2f(0.0f, 0.0f);
		gl.glVertex3d(0, 0, doors[7]);
		gl.glTexCoord2f(0.0f,4.0f);
		gl.glVertex3d(0, sizeY, doors[7]);
		

		///
		gl.glTexCoord2f(8f, 0.0f);
		gl.glVertex3d(0, 0, 0);
		gl.glTexCoord2f(8f,4.0f);
		gl.glVertex3d(0, sizeY, 0);
	    gl.glEnd();
	    // build floor
        gl.glTexParameteri ( GL.GL_TEXTURE_2D,GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT );
        gl.glTexParameteri( GL.GL_TEXTURE_2D,GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT );
        floorTexture.bind();
        
        gl.glBegin(GL.GL_QUAD_STRIP);
        
        gl.glTexCoord2f(0.0f, 0.0f);
		gl.glVertex3d(0,0 , 0);
		gl.glTexCoord2f(0.0f,8.0f);
		gl.glVertex3d(sizeX, 0, 0);
		
	
		if (startAbyss!=endAbyss){
			floorAbyss = new Point3D[4];
			gl.glTexCoord2f(4.0f, 0.0f);
			gl.glVertex3d(0, 0, startAbyss);
			gl.glTexCoord2f(4.0f,8.0f);
			gl.glVertex3d(sizeX, 0, startAbyss);
			
			gl.glTexCoord2f(0.0f, 0.0f);
			gl.glVertex3d(0, -1000, startAbyss);
			gl.glTexCoord2f(0.0f,8.0f);
			gl.glVertex3d(sizeX, -1000, startAbyss);
			
			
			//sideways
			gl.glEnd();
			gl.glBegin(GL.GL_QUAD_STRIP);

			gl.glTexCoord2f(4.0f, 0.0f);
			gl.glVertex3d(0, 0, startAbyss);
			gl.glTexCoord2f(4.0f,4.0f);
			gl.glVertex3d(0, 0, endAbyss);
			
			gl.glTexCoord2f(0.0f, 0.0f);
			gl.glVertex3d(0, -1000, startAbyss);
			gl.glTexCoord2f(0.0f,4.0f);
			gl.glVertex3d(0, -1000, endAbyss);
			
			
			gl.glEnd();
			gl.glBegin(GL.GL_QUAD_STRIP);
			
			gl.glTexCoord2f(4.0f, 0.0f);
			gl.glVertex3d(sizeX, 0, startAbyss);
			gl.glTexCoord2f(4.0f,4.0f);
			gl.glVertex3d(sizeX, 0, endAbyss);
			
			gl.glTexCoord2f(0.0f, 0.0f);
			gl.glVertex3d(sizeX, -1000, startAbyss);
			gl.glTexCoord2f(0.0f,4.0f);
			gl.glVertex3d(sizeX, -1000, endAbyss);
			
			
			gl.glEnd();
			gl.glBegin(GL.GL_QUAD_STRIP);
			
			//up and to the end
			gl.glTexCoord2f(0.0f, 0.0f);
			gl.glVertex3d(0, -1000, endAbyss);
			gl.glTexCoord2f(0.0f,8.0f);
			gl.glVertex3d(sizeX, -1000, endAbyss);
			
			
			gl.glTexCoord2f(4.0f, 0.0f);
			gl.glVertex3d(0, 0, endAbyss);
			gl.glTexCoord2f(4.0f,8.0f);
			gl.glVertex3d(sizeX, 0, endAbyss);
			 

			floorAbyss[0] = new Point3D(0, 0, startAbyss);
			floorAbyss[1] = new Point3D(0, 0, endAbyss);
			floorAbyss[2] = new Point3D(sizeX, 0, endAbyss);
			floorAbyss[3] = new Point3D(sizeX, 0, startAbyss);

			
			gl.glTexCoord2f(0.0f, 0.0f);
			gl.glVertex3d(0, 0, sizeZ);
			gl.glTexCoord2f(0.0f,8f);
			gl.glVertex3d(sizeX, 0, sizeZ);
			gl.glEnd();

		}

		else{
			gl.glTexCoord2f(4.0f, 0.0f);
			gl.glVertex3d(0, 0, sizeZ);
			gl.glTexCoord2f(4.0f,8f);
			gl.glVertex3d(sizeX, 0, sizeZ);
			gl.glEnd();
		}
	    gl.glTexParameteri ( GL.GL_TEXTURE_2D,GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT );
	    gl.glTexParameteri( GL.GL_TEXTURE_2D,GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT );
		
	    // build celling
	    cellingTexture.bind();
	    gl.glBegin(GL.GL_QUAD_STRIP);
        gl.glTexCoord2f(0.0f, 0.0f);
		gl.glVertex3d(0, sizeY, 0);
		gl.glTexCoord2f(0.0f,4f);
		gl.glVertex3d(0, sizeY, sizeZ);
		gl.glTexCoord2f(8f, 0.0f);
		gl.glVertex3d(sizeX, sizeY, 0);
		gl.glTexCoord2f(8f,4f);
		gl.glVertex3d(sizeX, sizeY, sizeZ);
		gl.glEnd();

		
		// add light
		float[] colorBlue   = {0.0f,0.0f,0.1f,1.0f};
		float[] color   = {0.7f,0.0f,0.6f,1.0f};

		
		float posLight1[] = { (float)(2*sizeX), (float)(-1*sizeY), (float)(sizeZ/3), 1f };
		float spotDirection[] = { 0f, 1f, 0f };
		gl.glLightfv( GL.GL_LIGHT1, GL.GL_POSITION, posLight1, 0 );
		gl.glLightf( GL.GL_LIGHT1, GL.GL_SPOT_CUTOFF, 50.0F );
		gl.glLightfv( GL.GL_LIGHT1, GL.GL_SPOT_DIRECTION, spotDirection, 0 );
  
		gl.glLightfv( GL.GL_LIGHT1, GL.GL_AMBIENT, colorBlue, 1 );
		gl.glLightfv( GL.GL_LIGHT1, GL.GL_DIFFUSE, color, 0 );
  
		gl.glLightf( GL.GL_LIGHT1, GL.GL_CONSTANT_ATTENUATION, 0.2f );		

	    gl.glEndList();
	    roomsWall.add(roomWall);
	    

		roomWall[4]=(new Point3D(sizeX+disp, 0, doors[2]));
		roomWall[5]=(new Point3D(sizeX+disp, 0, doors[3]));
		

		
		
	    
	    return room;
	}
 
	public void draw(GL gl) {
		
		
		
		gl.glCallList(room);
		
	    
		gl.glPushMatrix();
		
		pulldoorUp();
		gl.glTranslated(door1Pos,doorPosHight,forwardWall );
		gl.glRotated(90, 0, -1, 0);
		
		

		gl.glCallList(door);
		gl.glPopMatrix();
		
	}
	
	private void pulldoorUp(){
		if (switcher.active)
			if (doorPosHight<=celling+200)
				doorPosHight+=0.1;
		else{
			if (doorPosHight>=0)
				doorPosHight-=0.1;
		}
	}


	public Point3D[] getRoomWalls(int roomNumber) {
		return roomsWall.get(roomNumber);
	}


	public Point3D[] getFloorPoints() {
	
		return floorAbyss;
	}
	@Override
	public boolean checkDoorEnterance(Point3D eyePosition) {
		
		return (eyePosition.z>(forwardWall-100) && eyePosition.x<800 &&eyePosition.x>500 && switcher.active);
	}
	
}

